<?php

declare (strict_types=1);

namespace app\api\service;

use app\api\model\User as UserModel;
use app\api\model\UserOauth as UserOauthModel;
use app\api\service\applets\Base as MiniBaseService;
use app\api\service\passport\Login;
use app\common\library\helper;
use app\common\service\BaseService;
use app\common\service\ShortSms;
use cores\exception\BaseException;
use think\facade\Cache;
use think\facade\Config;
use think\facade\Log;

/**
 * 用户服务类
 * Class User
 * @package app\api\service
 */
class User extends BaseService
{
    // 当前登录的会员信息
    private static $currentLoginUser;

    /**
     * 获取当前登录的用户信息 (快捷)
     * 可在api应用中的任意模块中调用此方法(controller model service)
     * 已登录情况下返回用户信息, 未登录返回false
     * @param bool $isForce 是否强制验证登录, 如果未登录将抛错
     * @return false|UserModel
     * @throws BaseException
     */
    public static function getCurrentLoginUser(bool $isForce = false)
    {
        $service = new static;
        if (empty(static::$currentLoginUser)) {
            static::$currentLoginUser = $service->getLoginUser();
            if (empty(static::$currentLoginUser)) {
                $isForce && throwError($service->getError(), config('status.not_logged'));
                return false;
            }
        }
        return static::$currentLoginUser;
    }

    /**
     * 获取当前登录的用户ID
     * getCurrentLoginUser方法的二次封装
     * @return mixed
     * @throws BaseException
     */
    public static function getCurrentLoginUserId()
    {
        $userInfo = static::getCurrentLoginUser(true);
        return $userInfo['user_id'];
    }

    /**
     * 获取第三方用户信息
     * @param int $userId 用户ID
     * @param string $oauthType 第三方登陆类型
     * @return array|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getOauth(int $userId, $oauthType = 'MP-WEIXIN')
    {
        return UserOauthModel::getOauth($userId, $oauthType);
    }

    /**
     * 验证是否已登录
     * @param bool $isForce 是否强制验证登录, 如果未登录将抛错
     * @return bool
     * @throws BaseException
     */
    public static function isLogin(bool $isForce = false)
    {
        return !empty(static::getCurrentLoginUser($isForce));
    }

    /**
     * 获取当前登录的用户信息
     * @return UserModel|array|false|null
     * @throws BaseException
     */
    private function getLoginUser()
    {
        // 获取用户认证Token
        if (!$token = $this->getToken()) {
            return false;
        }
        // 获取用户信息
        if (!$user = UserModel::getUserByToken($token)) {
            $this->error = '没有找到用户信息';
            return false;
        }
        return $user;
    }

    /**
     * 获取用户认证Token
     * @return bool|string
     */
    protected function getToken()
    {
        // 获取请求中的token
        $token = $this->request->header('Access-Token');
        // 调试模式下可通过param
        if (empty($token)) {
            $token = $this->request->param('token');
        }

        // 不存在token报错
        if (empty($token)) {
            $this->error = '缺少必要的参数token, 请先登录';
            return false;
        }
        return $token;
    }

    //更新用户信息
    public function update($params){
        $userInfo = User::getCurrentLoginUser(true);
        $condition = [
            ['user_id','<>',$userInfo->user_id],
            ['mobile','=',$params['mobile']],
            ['mobile','<>',''],
        ];
        $find = UserModel::where($condition)->lock(true)->find();
        if($find){
            throwError("该手机号已被用户【{$find->nick_name}】绑定,请更换其他手机号码");
        }

        if(strlen($params['nick_name']) > 50){
            throwError("长度超出限制");
        }
        $userInfo->avatar_url = $params['avatar_url'] ?? '';
        $userInfo->nick_name = htmlspecialchars(addslashes($params['nick_name']));
        $userInfo->gender = $params['gender'] ?? 0;
        $userInfo->mobile = $params['mobile'];
        $userInfo->save();
        return true;
    }




    //退出登录
    public function loginOut(string $access_token){
        $user_info = UserModel::getUserByToken($access_token);
        if(!$user_info){
            throwError('未找到用户信息',401);
        }
        $redis = Cache::store('redis');
        // 检查登录态是否存在
        $hash = (new Login())::TOKEN_PREFIX;
        $redis->select(0);
        $hash_token = $redis->hget($hash,$access_token);
        if (!$hash_token) {
            return false;
        }
        $redis->hdel($hash,$access_token);
        return true;
    }

    //获取手机号信息
    public function getMobile($code): array
    {
        // $user_id = static::getCurrentLoginUserId();
        // if(!$user_id){
        //     throwError('token已过期');
        // }
        $mini_service = new MiniBaseService();
        $access_token = $mini_service->getAccessToken();
        $api_url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token='.$access_token;
        $postData = [
            'code' => $code,
        ];
        $res = curl_post_https($api_url,json_encode($postData));
        $res = helper::jsonDecode($res);
        Log::info('得到的weixin code 信息是'.json_encode($res,JSON_UNESCAPED_UNICODE));
        return [
            'phone' => $res['phone_info']['phoneNumber'] ?? '',
        ];
    }

    /**绑定手机号
     * @param $params
     * @return bool
     */
    public function bindMobile($params,$access_token):array
    {
        $old_user_id = User::getCurrentLoginUserId();
        $user = UserModel::where(['is_delete' => 0,'user_id' => $old_user_id])->find();
        if(!$user) {
            throwError('账户不存在或已被删除');
        }
        if($user->mobile != ''){
            throwError('已有手机号,无需绑定');
        }

        //如果是非微信获取手机号需要校验验证码
        if($params['type'] == 2){
            // 验证短信验证码是否匹配(测试环境不校验)
            if (!Config::get('app.debug')) {
                if (!(new ShortSms())->checkSms($params['smsCode'], $params['mobile'])) {
                    throwError('短信验证码不正确');
                }
            }
        }
        $check_mobile = UserModel::where(['is_delete' => 0,'mobile' => $params['mobile']])->find();
        if($check_mobile){
            //已有用户--- 将当前用户删除，替换成新用户
            $user->is_delete = 1;
            $user->save();
            //将微信auth_id记录也删掉
            $condition = [
                ['user_id','=',$user->user_id],
                ['is_delete','=',0]
            ];
            $oauth = UserOauthModel::where($condition)->find();
            if($oauth){
                $oauth->is_delete = 1;
                $oauth->save();
            }
            //token更新成手机号用户信息
            Cache::set($access_token, [
                'user' => $check_mobile,
                'store_id' => $this->storeId,
                'is_login' => true,
            ], 86400 * 30);
            $userInfo = $check_mobile;
        }else{
            //手机号新用户
            $user->mobile = $params['mobile'];
            $user->save();
            $userInfo = $user;
        }
        return [
            'info' => $userInfo->toArray()
        ];
    }

    /**资产
     * @return array
     */
    public function assets():array
    {
        // 当前用户信息
        $userInfo = $this->getCurrentLoginUser(true);
        return [
            'assets' => [
                'balance' => $userInfo['balance'],  // 账户余额
                'points' => $userInfo->points,    // 会员积分
                'coins' => $userInfo->coins,      //会员金币
            ]
        ];
    }

    /**补充邀请码--- 三天内
     * @param $params
     * @return bool
     */
    public function supplementInvitationCode($params):bool
    {

    }

}
